package libra;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;

@RestController
@RequestMapping("rest")
public class TestRestController {
	
	/*
	 * 在Nacos整合SpringCloud之后
	 * 我们无法再通过@NacosInjected从Spring容器中获取NamingService实例
	 */
	@NacosInjected
	private NamingService naming;
	@PostConstruct
	public void init() throws NacosException {
		System.out.println("NamingService:" + naming);
	}
	
	// 获取配置中当前应用的服务名
	@Value("${spring.cloud.nacos.discovery.service}")
	String serviceName;
	
	// 获取开启了LoadBalanced负载均衡的RestTemplate
	@Autowired
	RestTemplate restTemplate;
	
	// 获取服务实例
	@RequestMapping("testProvider")
	public Object getRegisterInstance(HttpServletRequest req, HttpServletResponse resp) throws NacosException {
		return restTemplate.postForObject("http://"+ serviceName +"/Ver3_SpringCloud/testReq", null, Map.class);
	}
	
	// 该接口需要启动Ver2_SpringBoot项目配合测试
	@RequestMapping("testBoot")
	public Object testBoot(HttpServletRequest req, HttpServletResponse resp) throws NacosException {
		return restTemplate.postForObject(
			"http://springboot-byCoding/Ver2_SpringBoot/getRegisterInstance?serviceName=springboot-byConfig", null, Object.class);
	}
	
	/*
	 * DiscoveryClient是Spring定义的顶级根接口，其主要用于实现'服务的发现'。
	 * 我们只需要通过@autowired从容器获取到DiscoveryClient的对应子实现, 负载均衡可以通过获取'DiscoveryClient实例'手动编码实现。
	 */
	@Autowired
	DiscoveryClient discoveryClient;
	
	@RequestMapping("DiscoveryClient")
	public Object discoveryClient( HttpServletRequest req ){
		Map<String, Object> result = new HashMap<String, Object>();
		// 获取NacosDiscovery服务注册中心的注册服务列表
		List<String> services = discoveryClient.getServices();
		// 循环解析注册服务列表
		for (String serviceName : services) {
			List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
			result.put(serviceName, list);
			// 通过服务名，获取所有的服务实例
			List<ServiceInstance> srvList = discoveryClient.getInstances(serviceName);
			// 循环解析当前服务名下对应的每一个服务实例的相关属性
			for( ServiceInstance si : srvList ) {
				Map<String, Object> instance = new HashMap<String, Object>();
				instance.put("getServiceId", si.getServiceId());
				instance.put("getHost", si.getHost());
				instance.put("getPort", si.getPort());
				instance.put("getUri", si.getUri());
				instance.put("getInstanceId", si.getInstanceId());
				instance.put("getScheme", si.getScheme());
				instance.put("getMetadata", si.getMetadata());
				
				list.add(instance);
			}
		}
		return result;
	}
}
